cmake_minimum_required(VERSION 3.16)

# 项目信息
project(IMChat 
    VERSION 1.0.0
    DESCRIPTION "A simple C++ IM chat system using TCP sockets"
    LANGUAGES CXX
)

# 设置C++标准
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)

# 编译选项
if(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang")
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra")
    set(CMAKE_CXX_FLAGS_DEBUG "-g -O0 -DDEBUG")
    set(CMAKE_CXX_FLAGS_RELEASE "-O2 -DNDEBUG")
endif()

# 查找线程库 
find_package(Threads REQUIRED)

# 查找MySQL库
find_package(PkgConfig REQUIRED)
pkg_check_modules(MYSQL REQUIRED mysqlclient)

# 设置输出目录
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)

# 包含头文件目录
include_directories(${CMAKE_SOURCE_DIR})
include_directories(${CMAKE_SOURCE_DIR}/include)

# 公共头文件
set(COMMON_HEADERS
    include/core/common.h
    include/core/enhanced_chat_system.h
    include/core/enhanced_chat_system_db.h
    include/core/database_manager.h
)

# 增强聊天系统服务器可执行文件
add_executable(enhanced_server
    src/enhanced_server.cpp
    src/enhanced_chat_system_db.cpp
    src/database_manager.cpp
    ${COMMON_HEADERS}
)

# 原始服务器可执行文件
add_executable(server
    src/server.cpp
    ${COMMON_HEADERS}
)

# 客户端可执行文件  
add_executable(client
    src/client.cpp
    ${COMMON_HEADERS}
)

# === 演示程序 ===

# 聊天对比演示程序
add_executable(chat_comparison_demo
    src/chat_comparison_fixed.cpp
)

# 群聊演示程序
add_executable(group_demo
    src/group_demo.cpp
)

# 群聊完整演示程序
add_executable(group_chat_demo
    src/group_chat_demo.cpp
)

# 运行群聊演示程序
add_executable(run_group_chat
    src/run_group_chat.cpp
)

# 私聊演示程序
add_executable(simple_chat_demo
    src/simple_chat_demo.cpp
)

# 链接线程库和MySQL库
target_link_libraries(enhanced_server PRIVATE Threads::Threads ${MYSQL_LIBRARIES})
target_link_libraries(server PRIVATE Threads::Threads)
target_link_libraries(client PRIVATE Threads::Threads)

# 演示程序链接线程库
target_link_libraries(chat_comparison_demo PRIVATE Threads::Threads)
target_link_libraries(group_demo PRIVATE Threads::Threads)
target_link_libraries(group_chat_demo PRIVATE Threads::Threads)
target_link_libraries(run_group_chat PRIVATE Threads::Threads)
target_link_libraries(simple_chat_demo PRIVATE Threads::Threads)

# 设置包含目录
target_include_directories(enhanced_server PRIVATE ${MYSQL_INCLUDE_DIRS})

# 设置目标属性
set_target_properties(enhanced_server PROPERTIES
    OUTPUT_NAME "enhanced_server"
    RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin
)

set_target_properties(server PROPERTIES
    OUTPUT_NAME "server"
    RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin
)

set_target_properties(client PROPERTIES
    OUTPUT_NAME "client"
    RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin
)

# 演示程序属性
set_target_properties(chat_comparison_demo PROPERTIES
    OUTPUT_NAME "chat_comparison_demo"
    RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin
)

set_target_properties(group_demo PROPERTIES
    OUTPUT_NAME "group_demo"
    RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin
)

set_target_properties(group_chat_demo PROPERTIES
    OUTPUT_NAME "group_chat_demo"
    RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin
)

set_target_properties(run_group_chat PROPERTIES
    OUTPUT_NAME "run_group_chat"
    RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin
)

set_target_properties(simple_chat_demo PROPERTIES
    OUTPUT_NAME "simple_chat_demo"
    RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin
)

# 编译特性
target_compile_features(enhanced_server PRIVATE cxx_std_17)
target_compile_features(server PRIVATE cxx_std_17)
target_compile_features(client PRIVATE cxx_std_17)

# 演示程序编译特性
target_compile_features(chat_comparison_demo PRIVATE cxx_std_17)
target_compile_features(group_demo PRIVATE cxx_std_17)
target_compile_features(group_chat_demo PRIVATE cxx_std_17)
target_compile_features(run_group_chat PRIVATE cxx_std_17)
target_compile_features(simple_chat_demo PRIVATE cxx_std_17)

# 安装配置
include(GNUInstallDirs)

install(TARGETS server client
    RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
    COMPONENT Runtime
)

install(FILES README.md
    DESTINATION ${CMAKE_INSTALL_DOCDIR}
    COMPONENT Documentation
)

# 打包配置
set(CPACK_PACKAGE_NAME "IMChat")
set(CPACK_PACKAGE_VERSION ${PROJECT_VERSION})
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY ${PROJECT_DESCRIPTION})
set(CPACK_PACKAGE_VENDOR "IM Chat Project Team")
set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_SOURCE_DIR}/LICENSE")
set(CPACK_RESOURCE_FILE_README "${CMAKE_SOURCE_DIR}/README.md")

# 根据平台选择打包格式
if(WIN32)
    set(CPACK_GENERATOR "ZIP;NSIS")
elseif(APPLE)
    set(CPACK_GENERATOR "ZIP;DragNDrop")
else()
    set(CPACK_GENERATOR "TGZ;DEB;RPM")
endif()

include(CPack)

# 添加自定义目标
add_custom_target(run-server
    COMMAND ${CMAKE_BINARY_DIR}/bin/server
    DEPENDS server
    WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/bin
    COMMENT "Running the chat server"
)

add_custom_target(run-client
    COMMAND ${CMAKE_BINARY_DIR}/bin/client
    DEPENDS client
    WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/bin
    COMMENT "Running the chat client"
)

# 演示程序运行目标
add_custom_target(run-chat-comparison
    COMMAND ${CMAKE_BINARY_DIR}/bin/chat_comparison_demo
    DEPENDS chat_comparison_demo
    WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/bin
    COMMENT "Running the chat comparison demo"
)

add_custom_target(run-group-demo
    COMMAND ${CMAKE_BINARY_DIR}/bin/group_demo
    DEPENDS group_demo
    WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/bin
    COMMENT "Running the group chat demo"
)

add_custom_target(run-group-chat-demo
    COMMAND ${CMAKE_BINARY_DIR}/bin/group_chat_demo
    DEPENDS group_chat_demo
    WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/bin
    COMMENT "Running the group chat full demo"
)

add_custom_target(run-group-chat
    COMMAND ${CMAKE_BINARY_DIR}/bin/run_group_chat
    DEPENDS run_group_chat
    WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/bin
    COMMENT "Running the group chat interactive demo"
)

add_custom_target(run-simple-chat
    COMMAND ${CMAKE_BINARY_DIR}/bin/simple_chat_demo
    DEPENDS simple_chat_demo
    WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/bin
    COMMENT "Running the simple chat demo"
)

# 演示程序集合目标
add_custom_target(demos
    DEPENDS chat_comparison_demo group_demo group_chat_demo run_group_chat simple_chat_demo
    COMMENT "Building all demo programs"
)

# 代码格式化目标 (如果安装了clang-format)
find_program(CLANG_FORMAT_EXECUTABLE clang-format)
if(CLANG_FORMAT_EXECUTABLE)
    add_custom_target(format
        COMMAND ${CLANG_FORMAT_EXECUTABLE} -i src/*.cpp *.h include/**/*.h
        WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
        COMMENT "Formatting source code with clang-format"
    )
endif()

# 显示配置信息
message(STATUS "")
message(STATUS "============== Build Configuration ==============")
message(STATUS "Project: ${PROJECT_NAME} v${PROJECT_VERSION}")
message(STATUS "Build Type: ${CMAKE_BUILD_TYPE}")
message(STATUS "C++ Standard: ${CMAKE_CXX_STANDARD}")
message(STATUS "Compiler: ${CMAKE_CXX_COMPILER_ID} ${CMAKE_CXX_COMPILER_VERSION}")
message(STATUS "Install Prefix: ${CMAKE_INSTALL_PREFIX}")
message(STATUS "")
message(STATUS "============== Available Targets ================")
message(STATUS "Core programs:")
message(STATUS "  server               - Main chat server")
message(STATUS "  client               - Chat client")
message(STATUS "  enhanced_server      - Enhanced server with database")
message(STATUS "")
message(STATUS "Demo programs:")
message(STATUS "  chat_comparison_demo - Private chat vs Group chat comparison")
message(STATUS "  group_demo           - Simple group chat demo")
message(STATUS "  group_chat_demo      - Full group chat demo")
message(STATUS "  run_group_chat       - Interactive group chat demo")
message(STATUS "  simple_chat_demo     - Simple private chat demo")
message(STATUS "")
message(STATUS "Build shortcuts:")
message(STATUS "  make demos           - Build all demo programs")
message(STATUS "  make run-server      - Build and run server")
message(STATUS "  make run-client      - Build and run client")
message(STATUS "  make run-chat-comparison - Run chat comparison demo")
message(STATUS "=================================================")
message(STATUS "") 